import network
import socket
import time
import machine
import ujson

# 引脚定义
LED_PIN = 2  # LED
BUTTON_PIN = 0  # 按键

# 状态定义
WIFI_CONFIG_FILE = "wifi_config.json"
AP_SSID = "ESP32S3_Config"

# 初始化硬件
led = machine.Pin(LED_PIN, machine.Pin.OUT)
button = machine.Pin(BUTTON_PIN, machine.Pin.IN, machine.Pin.PULL_UP)


# WiFi 连接函数
def connect_to_wifi(ssid, password):
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(ssid, password)
    for _ in range(20):  # 等待连接
        if wlan.isconnected():
            return True
        time.sleep(0.5)
    return False


# 启动 AP 模式
def start_ap_mode():
    wlan = network.WLAN(network.AP_IF)
    wlan.active(True)
    wlan.config(essid=AP_SSID, authmode=network.AUTH_OPEN)
    return wlan


# 保存 WiFi 配置
def save_wifi_config(ssid, password):
    with open(WIFI_CONFIG_FILE, "w") as f:
        ujson.dump({"ssid": ssid, "password": password}, f)


# 加载 WiFi 配置
def load_wifi_config():
    try:
        with open(WIFI_CONFIG_FILE, "r") as f:
            return ujson.load(f)
    except OSError:
        return None


# 配网页面
def config_page(wifi_list):
    wifi_options = "".join([f'<option value="{net[0]}">{net[0]}</option>' for net in wifi_list])
    return f"""
    <!DOCTYPE html>
    <html>
    <head><title>WiFi 配置</title></head>
    <body>
    <h1>WiFi 配置</h1>
    <form action="/configure" method="post">
        <label for="wifi">WiFi 信号:</label>
        <select id="wifi" name="wifi" onchange="document.getElementById('ssid').value=this.value">
            {wifi_options}
        </select>
        <button type="button" onclick="location.href='/scan'">刷新</button><br><br>
        <label for="ssid">WiFi 名称:</label>
        <input type="text" id="ssid" name="ssid"><br><br>
        <label for="password">WiFi 密码:</label>
        <input type="password" id="password" name="password"><br><br>
        <button type="submit">提交</button>
    </form>
    </body>
    </html>
    """


# 配网主流程
def wifi_config_mode():
    wlan = start_ap_mode()
    led_blinking(led, 0.2)

    addr = socket.getaddrinfo("0.0.0.0", 80)[0][-1]
    s = socket.socket()
    s.bind(addr)
    s.listen(1)
    print("Web server started on", addr)

    while True:
        conn, addr = s.accept()
        print("Connection from", addr)
        request = conn.recv(1024).decode("utf-8")
        print("Request:", request)

        # 处理扫描请求
        if "GET /scan" in request:
            wifi_list = wlan.scan()
            response = config_page(wifi_list)
        # 处理配置提交
        elif "POST /configure" in request:
            headers, body = request.split("\r\n\r\n", 1)
            params = {key: value for key, value in [x.split("=") for x in body.split("&")]}
            ssid = params.get("ssid")
            password = params.get("password")
            save_wifi_config(ssid, password)
            response = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n配置成功，请重启设备。"
            conn.sendall(response.encode("utf-8"))
            break
        else:
            response = config_page([])

        conn.sendall("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n".encode("utf-8") + response.encode("utf-8"))
        conn.close()

    wlan.active(False)


# LED 闪烁函数
def led_blinking(led, interval):
    while True:
        led.on()
        time.sleep(interval)
        led.off()
        time.sleep(interval)


# 主函数
def main():
    # 检测 WiFi 配置
    wifi_config = load_wifi_config()
    if wifi_config:
        ssid = wifi_config["ssid"]
        password = wifi_config["password"]
        if connect_to_wifi(ssid, password):
            led.on()  # 网络连接成功
            print("Connected to WiFi:", ssid)
        else:
            print("Failed to connect to WiFi. Starting config mode.")
            wifi_config_mode()
    else:
        print("No WiFi configuration found. Starting config mode.")
        wifi_config_mode()


# 按键长按检测
def button_press_detect():
    count = 0
    while True:
        if not button.value():  # 按键按下
            count += 1
            time.sleep(0.1)
            if count > 50:  # 长按 5 秒
                wifi_config_mode()
                break
        else:
            count = 0
        time.sleep(0.1)


# 启动
if __name__ == "__main__":
    main()
